/**
 * Copyright 2011 The Apache Software Foundation
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package idv.takeshi.model;

import java.util.ArrayList;
import java.util.List;
import java.util.Collections;

import org.apache.commons.lang.Validate;
import org.apache.commons.lang.builder.EqualsBuilder;

/**
 * @author takeshi.miao
 *
 */
public class Person extends Entity<Person> {
	
	private static final long serialVersionUID = 2703500559113124625L;

	private Long id;
	
	private String lastName;
	
	private String firstName;
	
	private String accountName;
	
	private String password;
	
	private List<RoleRelationship> roleRelationships = new ArrayList<RoleRelationship>();

	/**
	 * @return the id
	 */
	public Long getId() {
		return id;
	}

	/**
	 * @param id the id to set
	 */
	public void setId(Long id) {
		this.id = id;
	}

	/**
	 * @return the lastName
	 */
	public String getLastName() {
		return lastName;
	}

	/**
	 * @param lastName the lastName to set
	 */
	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	/**
	 * @return the firstName
	 */
	public String getFirstName() {
		return firstName;
	}

	/**
	 * @param firstName the firstName to set
	 */
	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	/**
	 * @return the accountName
	 */
	public String getAccountName() {
		return accountName;
	}

	/**
	 * @param accountName the accountName to set
	 */
	public void setAccountName(String accountName) {
		this.accountName = accountName;
	}

	/**
	 * @return the password
	 */
	public String getPassword() {
		return password;
	}

	/**
	 * @param password the password to set
	 */
	public void setPassword(String password) {
		this.password = password;
	}

	/**
	 * @return the roleRelationships
	 */
	public List<RoleRelationship> getRoleRelationships() {
		return this.roleRelationships;
	}
	
	/**
	 * @param roleRelationships the roleRelationships to set
	 */
	public void setRoleRelationships(List<RoleRelationship> roleRelationships) {
		this.roleRelationships = roleRelationships;
	}

	public void addRole(Role role) throws RoleAlreadyAssignedException{
		Validate.notNull(role, "role shall always not be null");
		for(RoleRelationship roleRelationship : this.roleRelationships){
			if(roleRelationship.getRole().equals(role)){
				throw new RoleAlreadyAssignedException("role:" + role.getName() + " already assigned!!");
			}
		}
		//if role is not assigned
		RoleRelationship roleRelationship = new RoleRelationship();
		roleRelationship.setPersonId(this.id);
		roleRelationship.setRoleId(role.getId());
		roleRelationship.setRole(role);
		this.roleRelationships.add(roleRelationship);
	}
	
	/**
	 * Get Roles of this Person.
	 * @return
	 */
	public List<Role> getRoles(){
		List<Role> roles = new ArrayList<Role>();
		for(RoleRelationship roleRelationship : this.roleRelationships){
			roles.add(roleRelationship.getRole());
		}
		return roles;
	}

	/* (non-Javadoc)
	 * @see idv.takeshi.model.Entity#equalsByKey(idv.takeshi.model.Entity)
	 */
	@Override
	public boolean equalsByKey(Person person) {
		if(null == person) return false;
		return new EqualsBuilder()
			.append(this.id, person.id)
			.isEquals();
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (obj == null) { return false; }
		if (obj == this) { return true; }
		if (!(obj instanceof Person)) {
			return false;
		}
		Person person = (Person)obj;
		return this.equalsByKey(person);
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		return this.id.hashCode();
	}

}
